﻿// ***********************************************************************
// Assembly         : Common.OjbectPool
// Author           : xiaofu
// Created          : 12-30-2014
//
// Last Modified By : xiaofu
// Last Modified On : 12-30-2014
// ***********************************************************************
// <copyright file="IPooledObject.cs" company="Microsoft">
//     Copyright (c) Microsoft. All rights reserved.
// </copyright>
// <summary></summary>
// ***********************************************************************
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace Common.OjbectPool
{
    /// <summary>
    /// Defines the wrapper that is used to track the additional information, such as state, for the pooled objects.
    /// Implementations of this class are required to be thread-safe.
    /// </summary>
    /// <typeparam name="T">the type of object in the pool</typeparam>
    public interface IPooledObject<T> : IComparable<IPooledObject<T>>
    {
        /// <summary>
        /// Obtain the underlying object that is wrapped by this instance of
        /// </summary>
        /// <returns>`0.</returns>
        T GetObject();

        /// <summary>
        /// Obtain the time that this object was created.
        /// (using the same basis as{@link System#currentTimeMillis()}
        /// </summary>
        /// <returns>The creation time for the wrapped object</returns>
        long GetCreateTime();

        /// <summary>
        /// Obtain the time in milliseconds that this object last spent in the
        /// active state (it may still be active in which case subsequent calls will
        /// return an increased value).
        /// </summary>
        /// <returns>The time in milliseconds last spent in the active state</returns>
        long GetActiveTimeMillis();

        /// <summary>
        /// Obtain the time in milliseconds that this object last spend in  the
        /// idle state (it may still be idle in which case subsequent calls will
        /// return an increased value).
        /// </summary>
        /// <returns>The time in milliseconds last spent in the idle state</returns>
        long GetIdleTimeMillis();

        /// <summary>
        /// Obtain the time the wrapped object was last borrowed.
        /// </summary>
        /// <returns>The time the object was last borrowed</returns>
        long GetLastBorrowTime();

        /// <summary>
        /// Obtain the time the wrapped object was last returned.
        /// </summary>
        /// <returns>The time the object was last returned</returns>
        long GetLastReturnTime();

        /// <summary>
        /// Return an estimate of the last time this object was used.  If the class
        /// of the pooled object implements<see cref="TrackedUse" />, what is returned is
        /// the maximum of <see cref="TrackedUse#GetLastUsed()" /> and <see cref="GetLastBorrowTime()" />
        /// ; otherwise this method gives the same value as <see cref="GetLastBorrowTime()" />.
        /// </summary>
        /// <returns>the last time this object was used</returns>
        long GetLastUsedTime();

        /// <summary>
        /// Attempt to place the pooled object in the
        /// <see cref="PooledObjectState#EVICTION" /> state.
        /// </summary>
        /// <returns><code>true</code> if the object was placed in the
        ///   <see cref="PooledObjectState#EVICTION" /> state otherwise
        ///   <code>false</code></returns>
        Boolean StartEvictionTest();

        /// <summary>
        /// Called to inform the object that the eviction test has ended.
        /// </summary>
        /// <param name="idleQueue">The queue if idle objects to which the object should be returned</param>
        /// <returns>Currently not used</returns>
        Boolean EndEvictionTest(BlockingCollection<IPooledObject<T>> idleQueue);


        /// <summary>
        /// Allocates the object.
        /// </summary>
        /// <returns><code>true</code> if the original state was <see cref="PooledObjectState#IDLE" />IDLE</returns>
        Boolean Allocate();

        /// <summary>
        /// Deallocates the object and sets it <see cref="PooledObjectState#IDLE" />IDLE
        /// if it is currently <see cref="PooledObjectState#ALLOCATED" /> ALLOCATED.
        /// </summary>
        /// <returns><code>true</code> if the state was<see cref="PooledObjectState#ALLOCATED" />ALLOCATED</returns>
        Boolean Deallocate();

        /// <summary>
        /// Sets the state to <see cref=" PooledObjectState#INVALID" /> INVALID
        /// </summary>
        void Invalidate();
        

        /// <summary>
        /// Record the current stack trace as the last time the object was used
        /// </summary>
        void Use();

        /// <summary>
        /// Returns the state of this object.
        /// </summary>
        /// <returns>state</returns>
        PooledObjectState GetState();

        /// <summary>
        /// Marks the pooled object as abandoned.
        /// </summary>
        void MarkAbandoned();

        /// <summary>
        /// Marks the object as returning to the pool.
        /// </summary>
        void MarkReturning();
    }
}
